<script setup lang="ts">
import type { DropdownMixedOption } from 'naive-ui/es/dropdown/src/interface';
import { isFunction } from 'lodash-es';
import { MoreCircle32Regular } from '@vicons/fluent';

import type { ActionButton } from '@/components/table/src/types/action-button';
import { renderIcon } from '@/utils/common';

const props = defineProps<{
  row: Recordable;
  actionButtons: ActionButton[];
  maxVisibleActionButtons: number;
}>();

let commonOptions = shallowReactive<ActionButton[]>([]);
const moreOptions = shallowReactive<DropdownMixedOption[]>([]);
const displayedOperations = computed(() => {
  return props.actionButtons.filter(button => {
    if (isFunction(button.display)) {
      return button.display.call(undefined, props.row) ?? true;
    }
    return button.display ?? true;
  });
});
const hasMore = computed(() => displayedOperations.value.length > props.maxVisibleActionButtons);

watchImmediate(hasMore, hasMore => {
  if (hasMore) {
    displayedOperations.value.slice(props.maxVisibleActionButtons).forEach(operation => {
      const disabled = isFunction(operation.disabled)
        ? operation.disabled.call(undefined, props.row)
        : operation.disabled ?? false;

      const loading = isFunction(operation.loading)
        ? operation.loading.call(undefined, props.row)
        : operation.loading ?? false;

      moreOptions.push({
        key: operation.key,
        label: operation.name,
        icon: renderIcon(operation.icon),
        disabled: disabled || loading,
        onClick: operation.onClick,
        confirmation: operation.confirmation ?? false,
        confirmationTip: operation.confirmationTip,
      });
    });
    commonOptions = displayedOperations.value.slice(0, props.maxVisibleActionButtons);
  } else {
    commonOptions = displayedOperations.value;
  }
});

function handleClick(button: ActionButton) {
  button.onClick(props.row);
}

function handleSelect(_key: string | number, option: any) {
  option.onClick(props.row);
}
</script>

<template>
  <NSpace :size="6" justify="center" item-style="flex">
    <div v-for="button of commonOptions" :key="button.key">
      <NPopconfirm
        v-if="button.confirmation"
        :negative-button-props="{ size: 'tiny' }"
        :positive-button-props="{ size: 'tiny' }"
        @positive-click="handleClick(button)"
      >
        <template #trigger>
          <NButton
            size="tiny"
            :type="button.type"
            :secondary="button.secondary"
            :dashed="button.dashed"
            :ghost="button.ghost"
            :tertiary="button.tertiary"
            :text="button.text"
            :disabled="button.disabled"
          >
            <template #icon>
              <NIcon :component="button.icon" />
            </template>
            {{ button.name }}
          </NButton>
        </template>
        {{ button.confirmationTip }}
      </NPopconfirm>

      <NButton
        v-else
        size="tiny"
        :type="button.type"
        :secondary="button.secondary"
        :dashed="button.dashed"
        :ghost="button.ghost"
        :tertiary="button.tertiary"
        :text="button.text"
        :disabled="button.disabled"
        @click="handleClick(button)"
      >
        <template #icon>
          <NIcon :component="button.icon" />
        </template>
        {{ button.name }}
      </NButton>
    </div>

    <NDropdown v-if="hasMore" trigger="hover" :options="moreOptions" @select="handleSelect">
      <!-- TODO 完善弹出确认 -->
      <NButton size="tiny">
        <template #icon>
          <NIcon :component="MoreCircle32Regular" />
        </template>
        更多
      </NButton>
    </NDropdown>
  </NSpace>
</template>
